// temperature_curve.cpp
#include "temperature_curve.h"
#include "ui_temperature_curve.h"
#include "hong.h"
#include <QSharedPointer>
#include <QDebug>
#include <QLocale>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDateTime>

// 在构造函数初始化列表中移除固定范围常量
Temperature_Curve::Temperature_Curve(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Temperature_Curve),
    tempButtonState(false),
    humButtonState(false),
    isConnected(false),
    isCollectingTemperature(false),
    isCollectingHumidity(false),
    startTime(0),
    temperaturePlot(nullptr),
    humidityPlot(nullptr),
    overlayWidget(nullptr),
    highTempWarningLabel(nullptr),
    temperatureTimeoutTimer(nullptr),
    humidityTimeoutTimer(nullptr),
    temperatureTimeoutLabel(nullptr),
    humidityTimeoutLabel(nullptr),
    lastTemperatureTime(0),
    lastHumidityTime(0),
    temperatureTimeout(false),
    humidityTimeout(false),
    temperatureZeroCount(0),    // 新增：初始化零值计数
    humidityZeroCount(0),       // 新增：初始化零值计数
    HIGH_TEMP_THRESHOLD(32.0)
{
    ui->setupUi(this);

    // 初始化起始时间
    startTime = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0;

    // 初始化最近数据
    lastTemperature = 0.0;
    lastHumidity = 0.0;

    // 修改：初始化Y轴范围（温度25-35℃，湿度50-65%）
    tempMin = 25.0;    // 改为25℃
    tempMax = 35.0;    // 改为35℃
    humMin = 50.0;     // 改为50%
    humMax = 65.0;     // 改为65%

    // 初始化图表
    temperaturePlot = ui->widget;
    humidityPlot = ui->widget_2;
    setupTemperaturePlot();
    setupHumidityPlot();

    // 创建覆盖层widget（未连接状态显示）
    overlayWidget = new QWidget(this);
    overlayWidget->setGeometry(0, 0, this->width(), this->height());
    overlayWidget->setStyleSheet("background-color: rgba(128, 128, 128, 150);");
    overlayWidget->setVisible(true);

    // 在覆盖层上添加提示文字
    QLabel *label = new QLabel("设备未连接", overlayWidget);
    label->setAlignment(Qt::AlignCenter);
    label->setStyleSheet("color: red; font-size: 70px; background: transparent;");
    label->setGeometry(0, 0, this->width(), this->height());

    // 设置高温警告标签
    setupHighTempWarningLabel();

    // 设置按钮初始状态 - 状态0
    updateButtonStyles();

    // 连接按钮点击信号
    connect(ui->wendu_pushButton, &QPushButton::clicked, this, &Temperature_Curve::onTemperatureButtonClicked);
    connect(ui->shidu_pushButton, &QPushButton::clicked, this, &Temperature_Curve::onHumidityButtonClicked);

    // 修改：数据采集定时器改为0.5秒更新一次
    dataTimer = new QTimer(this);
    connect(dataTimer, &QTimer::timeout, this, &Temperature_Curve::updateCharts);
    dataTimer->setInterval(500); // 0.5秒间隔

    // 初始化超时检测定时器
    temperatureTimeoutTimer = new QTimer(this);
    humidityTimeoutTimer = new QTimer(this);
    connect(temperatureTimeoutTimer, &QTimer::timeout, this, &Temperature_Curve::checkTemperatureTimeout);
    connect(humidityTimeoutTimer, &QTimer::timeout, this, &Temperature_Curve::checkHumidityTimeout);

    // 设置超时检测间隔为3秒
    temperatureTimeoutTimer->setInterval(3000);
    humidityTimeoutTimer->setInterval(3000);

    // 初始化超时提示标签
    setupTimeoutLabels();
}

// 初始化超时提示标签 - 添加这个函数的实现
void Temperature_Curve::setupTimeoutLabels()
{
    // 温度超时标签
    temperatureTimeoutLabel = new QLabel(this);
    temperatureTimeoutLabel->setText("温度数据采集超时");
    temperatureTimeoutLabel->setAlignment(Qt::AlignCenter);
    temperatureTimeoutLabel->setStyleSheet("color: red; font-size: 30px; font-weight: bold; background-color: rgba(255, 255, 255, 200); border: 2px solid red; padding: 10px;");
    temperatureTimeoutLabel->setGeometry(temperaturePlot->geometry().center().x() - 150,
                                        temperaturePlot->geometry().top() + 20, 300, 50);
    temperatureTimeoutLabel->setVisible(false);

    // 湿度超时标签
    humidityTimeoutLabel = new QLabel(this);
    humidityTimeoutLabel->setText("湿度数据采集超时");
    humidityTimeoutLabel->setAlignment(Qt::AlignCenter);
    humidityTimeoutLabel->setStyleSheet("color: red; font-size: 30px; font-weight: bold; background-color: rgba(255, 255, 255, 200); border: 2px solid red; padding: 10px;");
    humidityTimeoutLabel->setGeometry(humidityPlot->geometry().center().x() - 150,
                                     humidityPlot->geometry().top() + 20, 300, 50);
    humidityTimeoutLabel->setVisible(false);
}

// 检查温度数据超时（基于连续零值）
void Temperature_Curve::checkTemperatureTimeout()
{
    if (!isCollectingTemperature) return;

    // 修改：检查连续零值计数是否达到阈值
    if (temperatureZeroCount >= ZERO_THRESHOLD) {
        temperatureTimeout = true;
        temperatureTimeoutLabel->setVisible(true);
        qDebug() << "[Temperature_Curve]: 温度数据采集超时（连续" << temperatureZeroCount << "次零值）";
    }
}

// 检查湿度数据超时（基于连续零值）
void Temperature_Curve::checkHumidityTimeout()
{
    if (!isCollectingHumidity) return;

    // 修改：检查连续零值计数是否达到阈值
    if (humidityZeroCount >= ZERO_THRESHOLD) {
        humidityTimeout = true;
        humidityTimeoutLabel->setVisible(true);
        qDebug() << "[Temperature_Curve]: 湿度数据采集超时（连续" << humidityZeroCount << "次零值）";
    }
}

void Temperature_Curve::dataUpSlot(const QByteArray &msg)
{
    if (!isConnected) {
        setConnectedState(true);
    }

    qDebug() << "[Temperature_Curve]: 收到MQTT消息:" << msg;
    QJsonDocument doc = QJsonDocument::fromJson(msg);
    if(!doc.isObject()) return;

    QJsonObject obj = doc.object();

    // 检查设备ID
    if(obj.contains("id")) {
        QString deviceId = obj["id"].toString();
        if(deviceId != "dev01") {
            qDebug() << "[Temperature_Curve]: 忽略非目标设备消息，设备ID:" << deviceId;
            return;
        }
    }

    // 解析温度数据
    if(obj.contains("temp")) {
        double temperature = obj["temp"].toDouble();
        if (temperature >= -50 && temperature <= 100) {
            lastTemperature = QString::number(temperature, 'f', 2).toDouble();
            lastTemperatureTime = QDateTime::currentMSecsSinceEpoch();

            // 修改：根据温度值更新零值计数
            if (temperature == 0.0) {
                temperatureZeroCount++;
                qDebug() << "[Temperature_Curve]: 温度值为0，连续零值计数:" << temperatureZeroCount;
            } else {
                temperatureZeroCount = 0; // 重置计数
                temperatureTimeout = false;
                temperatureTimeoutLabel->setVisible(false);
                qDebug() << "[Temperature_Curve]: 收到非零温度值，重置零值计数";
            }

            qDebug() << "[Temperature_Curve]: 温度数据:" << lastTemperature;

            // 检查高温警告
            checkHighTemperatureWarning(lastTemperature);

            // 动态调整温度Y轴范围
            updateTemperatureYRange(lastTemperature);
        } else {
            qDebug() << "[Temperature_Curve]: 温度数据超出范围:" << temperature;
        }
    }

    // 解析湿度数据
    if(obj.contains("hum")) {
        double humidity = obj["hum"].toDouble();
        if (humidity >= 0 && humidity <= 100) {
            lastHumidity = QString::number(humidity, 'f', 2).toDouble();
            lastHumidityTime = QDateTime::currentMSecsSinceEpoch();

            // 修改：根据湿度值更新零值计数
            if (humidity == 0.0) {
                humidityZeroCount++;
                qDebug() << "[Temperature_Curve]: 湿度值为0，连续零值计数:" << humidityZeroCount;
            } else {
                humidityZeroCount = 0; // 重置计数
                humidityTimeout = false;
                humidityTimeoutLabel->setVisible(false);
                qDebug() << "[Temperature_Curve]: 收到非零湿度值，重置零值计数";
            }

            qDebug() << "[Temperature_Curve]: 湿度数据:" << lastHumidity;

            // 动态调整湿度Y轴范围
            updateHumidityYRange(lastHumidity);
        } else {
            qDebug() << "[Temperature_Curve]: 湿度数据超出范围:" << humidity;
        }
    }
}

// 动态调整温度Y轴范围（限制在25-35℃范围内调整）
void Temperature_Curve::updateTemperatureYRange(double temperature)
{
    // 如果温度超出当前范围，调整范围（但限制在25-35℃之间）
    if (temperature < tempMin && temperature >= 25.0) {
        tempMin = qMax(25.0, temperature - 2); // 留出2度的余量，但不低于25℃
    } else if (temperature > tempMax && temperature <= 35.0) {
        tempMax = qMin(35.0, temperature + 2); // 留出2度的余量，但不高于35℃
    }

    // 确保最小显示范围
    if (tempMax - tempMin < 5) {
        double center = (tempMin + tempMax) / 2;
        tempMin = qMax(25.0, center - 2.5);
        tempMax = qMin(35.0, center + 2.5);
    }

    // 更新图表Y轴范围
    if (temperaturePlot) {
        temperaturePlot->yAxis->setRange(tempMin, tempMax);
    }
}

// 动态调整湿度Y轴范围（限制在50-65%范围内调整）
void Temperature_Curve::updateHumidityYRange(double humidity)
{
    // 如果湿度超出当前范围，调整范围（但限制在50-65%之间）
    if (humidity < humMin && humidity >= 50.0) {
        humMin = qMax(50.0, humidity - 5); // 留出5%的余量，但不低于50%
    } else if (humidity > humMax && humidity <= 65.0) {
        humMax = qMin(65.0, humidity + 5); // 留出5%的余量，但不高于65%
    }

    // 确保最小显示范围
    if (humMax - humMin < 10) {
        double center = (humMin + humMax) / 2;
        humMin = qMax(50.0, center - 5);
        humMax = qMin(65.0, center + 5);
    }

    // 更新图表Y轴范围
    if (humidityPlot) {
        humidityPlot->yAxis->setRange(humMin, humMax);
    }
}

// 修改高温警告检查函数
void Temperature_Curve::checkHighTemperatureWarning(double temperature)
{
    if (temperature > HIGH_TEMP_THRESHOLD) { // 使用新的阈值
        highTempWarningLabel->setVisible(true);
        highTempWarningLabel->raise(); // 确保在最上层
        qDebug() << "[Temperature_Curve]: 高温警告！当前温度:" << temperature;
    } else {
        highTempWarningLabel->setVisible(false);
    }
}

// 修改图表更新函数，每0.5秒更新一次
void Temperature_Curve::updateCharts()
{
    // 更新温度图表
    if (isCollectingTemperature && lastTemperature > -100) { // 放宽条件
        updateTemperatureChart(lastTemperature);
    }

    // 更新湿度图表
    if (isCollectingHumidity && lastHumidity >= 0) {
        updateHumidityChart(lastHumidity);
    }
}

// 修改温度按钮点击函数
void Temperature_Curve::onTemperatureButtonClicked()
{
    if (!isConnected) {
        qDebug() << "[Temperature_Curve]: 未连接MQTT，无法控制温度采集";
        return;
    }

    // 切换按钮状态
    tempButtonState = !tempButtonState;
    isCollectingTemperature = tempButtonState;

    // 更新按钮样式
    updateButtonStyles();

    qDebug() << "[Temperature_Curve]: 温度按钮状态切换为:" << tempButtonState;

    // 发送控制命令
    QJsonObject command;
    if (tempButtonState) {
        command["temp_down"] = 1;
        // 开始超时检测
        temperatureTimeoutTimer->start();
        lastTemperatureTime = QDateTime::currentMSecsSinceEpoch();
        temperatureTimeoutLabel->setVisible(false);

        // 新增：重置零值计数
        temperatureZeroCount = 0;
        temperatureTimeout = false;

        // 重置温度范围
        tempMin = lastTemperature - 5;
        tempMax = lastTemperature + 5;
        if (tempMin < -50) tempMin = -50;
        if (tempMax > 100) tempMax = 100;
    } else {
        command["temp_down"] = 0;
        // 停止超时检测
        temperatureTimeoutTimer->stop();
        temperatureTimeoutLabel->setVisible(false);

        // 新增：重置零值计数
        temperatureZeroCount = 0;
        temperatureTimeout = false;
    }

    sendControlCommand(command);

    // 控制数据更新定时器
    if (tempButtonState || humButtonState) {
        if (!dataTimer->isActive()) {
            dataTimer->start();
        }
    } else {
        dataTimer->stop();
    }
}

// 修改湿度按钮点击函数
void Temperature_Curve::onHumidityButtonClicked()
{
    if (!isConnected) {
        qDebug() << "[Temperature_Curve]: 未连接MQTT，无法控制湿度采集";
        return;
    }

    // 切换按钮状态
    humButtonState = !humButtonState;
    isCollectingHumidity = humButtonState;

    // 更新按钮样式
    updateButtonStyles();

    qDebug() << "[Temperature_Curve]: 湿度按钮状态切换为:" << humButtonState;

    // 发送控制命令
    QJsonObject command;
    if (humButtonState) {
        command["hum_down"] = 1;
        // 开始超时检测
        humidityTimeoutTimer->start();
        lastHumidityTime = QDateTime::currentMSecsSinceEpoch();
        humidityTimeoutLabel->setVisible(false);

        // 新增：重置零值计数
        humidityZeroCount = 0;
        humidityTimeout = false;

        // 重置湿度范围
        humMin = qMax(0.0, lastHumidity - 10);
        humMax = qMin(100.0, lastHumidity + 10);
    } else {
        command["hum_down"] = 0;
        // 停止超时检测
        humidityTimeoutTimer->stop();
        humidityTimeoutLabel->setVisible(false);

        // 新增：重置零值计数
        humidityZeroCount = 0;
        humidityTimeout = false;
    }

    sendControlCommand(command);

    // 控制数据更新定时器
    if (tempButtonState || humButtonState) {
        if (!dataTimer->isActive()) {
            dataTimer->start();
        }
    } else {
        dataTimer->stop();
    }
}

// 修改设置温度曲线图函数，使用动态Y轴范围
void Temperature_Curve::setupTemperaturePlot()
{
    if (!temperaturePlot) return;

    // 设置背景颜色
    temperaturePlot->setBackground(QBrush(QColor(240, 240, 240)));

    // 创建图形
    temperaturePlot->addGraph();
    temperaturePlot->graph(0)->setPen(QPen(Qt::red)); // 红色线条表示温度
    temperaturePlot->graph(0)->setName("温度"); // 设置图例名称

    // 设置坐标轴标签
    temperaturePlot->xAxis->setLabel("时间");
    temperaturePlot->yAxis->setLabel("温度 (°C)");

    // 设置初始Y轴范围（会动态调整）
    temperaturePlot->yAxis->setRange(tempMin, tempMax);

    // 设置Y轴刻度标签格式为小数点后两位
    temperaturePlot->yAxis->setNumberFormat("f");
    temperaturePlot->yAxis->setNumberPrecision(2);

    // 配置坐标轴样式
    QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
    dateTicker->setDateTimeFormat("hh:mm:ss");
    temperaturePlot->xAxis->setTicker(dateTicker);
    temperaturePlot->xAxis->grid()->setVisible(true);
    temperaturePlot->yAxis->grid()->setVisible(true);

    // 添加标题
    temperaturePlot->plotLayout()->insertRow(0);
    temperaturePlot->plotLayout()->addElement(0, 0,
        new QCPTextElement(temperaturePlot, "温度曲线", QFont("sans", 12, QFont::Bold)));

    // 显示图例
    temperaturePlot->legend->setVisible(true);
}

// 修改设置湿度曲线图函数，使用动态Y轴范围
void Temperature_Curve::setupHumidityPlot()
{
    if (!humidityPlot) return;

    // 设置背景颜色
    humidityPlot->setBackground(QBrush(QColor(240, 240, 240)));

    // 创建图形
    humidityPlot->addGraph();
    humidityPlot->graph(0)->setPen(QPen(Qt::blue)); // 蓝色线条表示湿度
    humidityPlot->graph(0)->setName("湿度"); // 设置图例名称

    // 设置坐标轴标签
    humidityPlot->xAxis->setLabel("时间");
    humidityPlot->yAxis->setLabel("湿度 (%)");

    // 设置初始Y轴范围（会动态调整）
    humidityPlot->yAxis->setRange(humMin, humMax);

    // 设置Y轴刻度标签格式为小数点后两位
    humidityPlot->yAxis->setNumberFormat("f");
    humidityPlot->yAxis->setNumberPrecision(2);

    // 配置坐标轴样式
    QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
    dateTicker->setDateTimeFormat("hh:mm:ss");
    humidityPlot->xAxis->setTicker(dateTicker);
    humidityPlot->xAxis->grid()->setVisible(true);
    humidityPlot->yAxis->grid()->setVisible(true);

    // 添加标题
    humidityPlot->plotLayout()->insertRow(0);
    humidityPlot->plotLayout()->addElement(0, 0,
        new QCPTextElement(humidityPlot, "湿度曲线", QFont("sans", 12, QFont::Bold)));

    // 显示图例
    humidityPlot->legend->setVisible(true);
}

void Temperature_Curve::stopAllCollection()
{
    tempButtonState = false;
    humButtonState = false;
    isCollectingTemperature = false;
    isCollectingHumidity = false;

    // 停止所有定时器
    dataTimer->stop();
    temperatureTimeoutTimer->stop();
    humidityTimeoutTimer->stop();

    // 隐藏超时提示
    temperatureTimeoutLabel->setVisible(false);
    humidityTimeoutLabel->setVisible(false);

    // 新增：重置零值计数
    temperatureZeroCount = 0;
    humidityZeroCount = 0;
    temperatureTimeout = false;
    humidityTimeout = false;

    // 清空数据
    timeData.clear();
    temperatureData.clear();
    timeDataHumidity.clear();
    humidityData.clear();

    // 重置按钮样式
    updateButtonStyles();

    // 隐藏高温警告
    highTempWarningLabel->setVisible(false);

    qDebug() << "[Temperature_Curve]: 停止所有数据采集";
}

// 更新温度数据到图表
void Temperature_Curve::updateTemperatureData(const QVector<double> &times, const QVector<double> &temperatures)
{
    if (!temperaturePlot) return;

    // 设置新数据
    temperaturePlot->graph(0)->setData(times, temperatures);

    // 自动调整X轴范围以显示所有数据
    if (!times.isEmpty()) {
        temperaturePlot->xAxis->setRange(times.first(), times.last());
    }

    // 重绘
    temperaturePlot->replot();
}

// 更新湿度数据到图表
void Temperature_Curve::updateHumidityData(const QVector<double> &times, const QVector<double> &humidities)
{
    if (!humidityPlot) return;

    // 设置新数据
    humidityPlot->graph(0)->setData(times, humidities);

    // 自动调整X轴范围以显示所有数据
    if (!times.isEmpty()) {
        humidityPlot->xAxis->setRange(times.first(), times.last());
    }

    // 重绘
    humidityPlot->replot();
}

// 更新温度图表
void Temperature_Curve::updateTemperatureChart(double temperature)
{
    // 获取当前时间（相对于起始时间的秒数）
    double currentTime = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0 - startTime;

    // 添加到数据向量
    timeData.append(currentTime);
    temperatureData.append(temperature);

    // 限制数据点数量，避免内存过度增长
    const int maxDataPoints = 200; // 增加数据点数量以适应更快的更新频率
    if (timeData.size() > maxDataPoints) {
        timeData.removeFirst();
        temperatureData.removeFirst();
    }

    // 更新图表显示
    updateTemperatureData(timeData, temperatureData);

    qDebug() << "[Temperature_Curve]: 温度图表更新，当前温度:" << temperature;
}

// 更新湿度图表
void Temperature_Curve::updateHumidityChart(double humidity)
{
    // 获取当前时间（相对于起始时间的秒数）
    double currentTime = QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0 - startTime;

    // 添加到数据向量
    timeDataHumidity.append(currentTime);
    humidityData.append(humidity);

    // 限制数据点数量，避免内存过度增长
    const int maxDataPoints = 200; // 增加数据点数量以适应更快的更新频率
    if (timeDataHumidity.size() > maxDataPoints) {
        timeDataHumidity.removeFirst();
        humidityData.removeFirst();
    }

    // 更新图表显示
    updateHumidityData(timeDataHumidity, humidityData);

    qDebug() << "[Temperature_Curve]: 湿度图表更新，当前湿度:" << humidity;
}

// 设置连接状态
void Temperature_Curve::setConnectedState(bool connected)
{
    isConnected = connected;
    if (!connected) {
        // 断开连接时停止所有采集
        stopAllCollection();
        overlayWidget->setVisible(true);
        updateButtonStyles();
        highTempWarningLabel->setVisible(false); // 断开连接时隐藏警告
    } else {
        overlayWidget->setVisible(false);
    }
}

// 发送控制命令
void Temperature_Curve::sendControlCommand(const QJsonObject& command)
{
    if (!GlobalVal::mqtt) {
        qDebug() << "[Temperature_Curve]: MQTT客户端未初始化";
        return;
    }

    QJsonDocument doc(command);
    QByteArray json = doc.toJson();

    QMQTT::Message mqttMessage;
    mqttMessage.setTopic("MQTT  rec");
    mqttMessage.setPayload(json);

    GlobalVal::mqtt->publish(mqttMessage);
    qDebug() << "[Temperature_Curve]: 发送控制命令:" << QString(json);
}

// 更新按钮样式
void Temperature_Curve::updateButtonStyles()
{
    // 温度按钮样式：状态为0显示CAIJI0，状态为1显示CAIJI1
    if (tempButtonState) {
        ui->wendu_pushButton->setStyleSheet("border-image: url(" CAIJI1 ");");
    } else {
        ui->wendu_pushButton->setStyleSheet("border-image: url(" CAIJI0 ");");
    }

    // 湿度按钮样式：状态为0显示CAIJI0，状态为1显示CAIJI1
    if (humButtonState) {
        ui->shidu_pushButton->setStyleSheet("border-image: url(" CAIJI1 ");");
    } else {
        ui->shidu_pushButton->setStyleSheet("border-image: url(" CAIJI0 ");");
    }
}

// 初始化高温警告标签
void Temperature_Curve::setupHighTempWarningLabel()
{
    highTempWarningLabel = new QLabel(this);
    highTempWarningLabel->setText("高温警告");
    highTempWarningLabel->setAlignment(Qt::AlignCenter);
    highTempWarningLabel->setStyleSheet("color: red; font-size: 40px; font-weight: bold; background-color: yellow; border: 2px solid red; padding: 10px;");
    highTempWarningLabel->setGeometry(this->width()/2 - 150, 20, 300, 60); // 顶部居中显示
    highTempWarningLabel->setVisible(false); // 初始隐藏
}

Temperature_Curve::~Temperature_Curve()
{
    delete ui;
    if (highTempWarningLabel) {
        delete highTempWarningLabel;
    }
    if (temperatureTimeoutLabel) {
        delete temperatureTimeoutLabel;
    }
    if (humidityTimeoutLabel) {
        delete humidityTimeoutLabel;
    }
}
